package task

import (
	"context"
	"encoding/json"
	"fmt"
	"qianggougo/controller/common"
	"qianggougo/model"
	"time"

	"github.com/robfig/cron/v3"
)

// 定义 Redis 队列名称
const (
	BulletQueueKey = "game:bullet:queue"
	BatchSize      = 100 // 每次处理的批量大小
)

type BulletInfo struct {
	Content string `json:"content"`
	Side    string `json:"side"`
	UserID  int    `json:"userid"`
}

type Request struct {
	Bullettype int        `json:"bullettype"`
	Bulletr    BulletInfo `json:"bulletr"`
	Bullethit  BulletInfo `json:"bullethit"` // 这里是切片，支持空数组
}

/**
 * 定时任务：从 Redis 读取数据并保存到 MySQL
 */
func StartBulletQueueConsumer() {
	c := cron.New()

	// 每5分钟执行一次（可根据需求调整）
	_, err := c.AddFunc("*/1 * * * *", func() {
		fmt.Println("开始处理 Redis 队列...", time.Now())
		processBulletQueue()
	})
	if err != nil {
		panic("定时任务启动失败: " + err.Error())
	}

	c.Start()
	fmt.Println("定时任务已启动，每5分钟检查一次队列")
}

// 处理队列数据
func processBulletQueue() {
	ctx := context.Background()

	// 1. 从 Redis 获取批量数据
	items, err := common.RDB.LRange(ctx, BulletQueueKey, 0, BatchSize-1).Result()
	if err != nil {
		fmt.Println("读取 Redis 队列失败:", err)
		return
	}

	if len(items) == 0 {
		fmt.Println("队列为空，无需处理")
		return
	}

	// 2. 批量保存到 MySQL
	if err := saveBulletsToMySQL(items); err != nil {
		fmt.Println("保存到 MySQL 失败:", err)
		return
	}

	// 3. 删除已处理的数据
	if _, err := common.RDB.LTrim(ctx, BulletQueueKey, int64(len(items)), -1).Result(); err != nil {
		fmt.Println("清理 Redis 队列失败:", err)
	}

	fmt.Printf("成功处理 %d 条数据\n", len(items))
}

// 把队列数据保存到mysql
func saveBulletsToMySQL(items []string) error {
	var bullets []model.Bullet

	for _, item := range items {
		var req Request
		if err := json.Unmarshal([]byte(item), &req); err != nil {
			fmt.Println("JSON 解析失败:", err)
			continue
		}

		now := time.Now()

		// 处理 bulletr（所有情况都要插入）
		bullets = append(bullets, model.Bullet{
			UserID:    req.Bulletr.UserID,
			Lineup:    getLineupCode(req.Bulletr.Side), // "red"->1, "blue"->2
			Content:   req.Bulletr.Content,
			IsSuccess: boolToInt(req.Bullettype == 1), // bullettype = 1 或 0
			CreatedAt: now,
		})

		// 处理 bullethit（bullettype=0 且字段非空时插入）
		if req.Bullettype == 0 && !isZeroBulletInfo(req.Bullethit) {
			bullets = append(bullets, model.Bullet{
				UserID:    req.Bullethit.UserID,
				Lineup:    getLineupCode(req.Bullethit.Side),
				Content:   req.Bullethit.Content,
				IsSuccess: 0, // 固定为失败
				CreatedAt: now,
			})
		}
	}

	// 批量插入
	if len(bullets) > 0 {
		if err := common.DB.CreateInBatches(bullets, len(bullets)).Error; err != nil {
			return err
		}
	}
	return nil
}

// 辅助函数：检查 BulletInfo 是否为空
func isZeroBulletInfo(b BulletInfo) bool {
	return b.Content == "" && b.Side == "" && b.UserID == 0
}

// 辅助函数：side 转 lineup 编码
func getLineupCode(side string) int8 {
	if side == "blue" {
		return 2
	}
	return 1 // 默认红队
}

// 辅助函数：bool 转 int8
func boolToInt(b bool) int8 {
	if b {
		return 1
	}
	return 0
}
